package org.zebra.captcha.mail;

import cn.hutool.aop.aspects.Aspect;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import org.dromara.email.jakarta.api.MailClient;
import org.dromara.email.jakarta.comm.entity.MailMessage;
import org.dromara.email.jakarta.core.factory.MailFactory;
import org.zebra.cache.util.RedisUtil;
import org.zebra.captcha.CaptchaHandler;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * 邮件验证码
 *
 * @author zhanghongbin
 */
public class MailCaptchaHandler implements CaptchaHandler<Boolean> {

    private int expirationTime;
    private int codeLength;
    private MailCaptchaTemplateSource mailCaptchaTemplateSource;
    private Aspect mailLogAspect;

    public MailCaptchaHandler(
            MailCaptchaTemplateSource mailCaptchaTemplateSource,
            Aspect mailLogAspect,
            int expirationTime,
            int codeLength) {
        this.mailCaptchaTemplateSource = mailCaptchaTemplateSource;
        this.mailLogAspect = mailLogAspect;
        this.expirationTime = expirationTime;
        this.codeLength = codeLength;
    }

    @Override
    public Boolean build(String name) {
        boolean flag;
        String key = CAPTCHA_KEY + name;
        String code = RandomUtil.randomNumbers(codeLength);
        RedisUtil.setCacheObject(RedisUtil.getRedisTemplate(), key, code, Duration.ofMinutes(this.expirationTime));
        String content = mailCaptchaTemplateSource.getMailContent(code, this.expirationTime);
        MailMessage message = MailMessage.Builder()
                .mailAddress(name)
                .title(mailCaptchaTemplateSource.getMailTitle())
                .body(content)
                .build();
        MailClient mailClient = MailFactory.createMailClient(mailCaptchaTemplateSource.getMail());
        if (mailClient == null) {
            throw ExceptionUtil.wrapRuntime("没有MailClient对象");
        }
        try {
            mailClient.send(message);
            flag = true;
        } catch (Exception e) {
            flag = false;
        }
        if (mailLogAspect != null) {
            try {
                Map<String, Object> params = new HashMap<>();
                params.put("title", mailCaptchaTemplateSource.getMailTitle());
                params.put("content", content);
                mailLogAspect.after(
                        this,
                        this.getClass().getMethod("build", String.class),
                        new Object[] {mailCaptchaTemplateSource.getMail(), name, params},
                        flag);
            } catch (Exception e) {
            }
        }
        return flag;
    }

    @Override
    public boolean check(String name, String code) {
        String verifyKey = CAPTCHA_KEY + name;
        String captcha = RedisUtil.getCacheObject(RedisUtil.getRedisTemplate(), verifyKey);
        RedisUtil.delete(RedisUtil.getRedisTemplate(), verifyKey);
        if (StrUtil.isBlank(captcha)) {
            return true;
        }
        return code.equals(captcha);
    }
}
